package main

import (
	"flag"
	"fmt"
	"log"
	"os"
	"os/signal"
	"syscall"
	"time"
	"ebbflow/src/consensus"
	"ebbflow/src/config"
	"ebbflow/src/message"
	"ebbflow/src/turritopsis"

	"ebbflow/src/communication"
)

const (
	helpText_ebbflow_server = `
EbbFlow Protocol Server
Usage: ebbflow_server [NodeID]
`
)

var (
	nodeID     = flag.Int("id", 0, "Node ID")
	totalNodes = flag.Int("n", 6, "Total number of nodes")
	faultyNodes = flag.Int("f", 1, "Number of faulty nodes")
	epochs    = flag.Int("epochs", 30, "Number of epochs to run")
	r         = flag.Int("r", 5, "ADKR execution interval (every R epochs)")
	verbose    = flag.Bool("v", false, "Verbose logging")
)

func main() {
	flag.Parse()
	
	if *nodeID < 0 || *nodeID >= *totalNodes {
		log.Fatal("Invalid node ID")
	}
	
	if *faultyNodes >= *totalNodes/2 {
		log.Fatal("Too many faulty nodes")
	}
	
	log.Printf("Starting EbbFlow Protocol Server")
	log.Printf("Node ID: %d, Total Nodes: %d, Faulty Nodes: %d, Epochs: %d, R: %d", 
		*nodeID, *totalNodes, *faultyNodes, *epochs, *r)
	
	// Load configuration
	config.LoadConfig()
	
	// Create communication channels
	msgInCh := make(chan message.ReplicaMessage, 1000)
	msgOutCh := make(chan message.ReplicaMessage, 1000)
	
	// Create ADKR message channels (simplified)
	adkrMsgInCh := make(chan interface{}, 100)
	adkrMsgOutCh := make(chan interface{}, 100)
	
	// Create integrated consensus
	consensus := consensus.NewEbbFlowConsensus(
		*nodeID, *totalNodes, *faultyNodes,
		msgInCh, msgOutCh,
	)
	
	// Create Turritopsis integration
	turritopsisIntegration := consensus.NewTurritopsisIntegration(
		*epochs, *r, *totalNodes, *faultyNodes, *nodeID, "ebbflow-test",
	)
	
	// Set components
	turritopsisIntegration.SetWaterBear(consensus)
	turritopsisIntegration.SetMessageChannels(msgInCh, msgOutCh)
	turritopsisIntegration.SetADKRChannels(adkrMsgInCh, adkrMsgOutCh)
	
	// Start consensus
	if err := consensus.Start(); err != nil {
		log.Fatalf("Failed to start consensus: %v", err)
	}
	
	// Start Turritopsis integration
	go func() {
		if err := turritopsisIntegration.Run(); err != nil {
			log.Printf("Turritopsis integration failed: %v", err)
		}
	}()
	
	// Start message handling
	go handleOutgoingMessages(msgOutCh)
	go handleIncomingMessages(msgInCh)
	
	// Start performance monitoring
	go monitorPerformance(consensus, turritopsisIntegration)
	
	// Handle shutdown signals
	sigChan := make(chan os.Signal, 1)
	signal.Notify(sigChan, syscall.SIGINT, syscall.SIGTERM)
	
	log.Printf("EbbFlow server started successfully")
	
	// Wait for shutdown signal
	<-sigChan
	log.Printf("Shutting down EbbFlow server...")
	
	// Stop consensus and integration
	consensus.Stop()
	turritopsisIntegration.Stop()
	
	log.Printf("EbbFlow server stopped")
}

func handleOutgoingMessages(msgOutCh <-chan message.ReplicaMessage) {
	for msg := range msgOutCh {
		// In a real implementation, this would send the message over the network
		// For now, we'll just log it
		if *verbose {
			log.Printf("Sending message: Type=%v, Instance=%d, Source=%d", 
				msg.Mtype, msg.Instance, msg.Source)
		}
		
		// Simulate network delay (reduced for higher throughput)
		// Network delay removed - using real network communication
	}
}

// handleIncomingMessages 真实的消息处理函数
func handleIncomingMessages(msgInCh chan<- message.ReplicaMessage) {
	// 使用gRPC接收真实消息
	// 这里将集成waterbear的receiver组件
	// 暂时保持空实现，等待gRPC集成
	log.Printf("Real message handling - gRPC integration pending")
}
	}
}

func monitorPerformance(consensus *consensus.EbbFlowConsensus, integration *consensus.TurritopsisIntegration) {
	ticker := time.NewTicker(5 * time.Second)
	// Ticker stop removed - using real message handling
	
	// Ticker loop removed - using real message handling
	// Real message handling will be implemented here
		status := consensus.GetProtocolStatus()
		metrics := integration.GetMetrics()
		log.Printf("Performance: Node=%d, Epoch=%v, Consensus=%v, TPS=%v, ADKR=%d", 
			status["node_id"], status["current_epoch"], 
			status["ebbflow/src/consensus_count"], status["tps"], metrics.ADKRExecutions)
	}
}
